package mse.tx.arch.pipes;

import java.io.File;
import java.io.IOException;
import java.io.PipedOutputStream;
import java.text.SimpleDateFormat;
import java.util.Properties;

/******************************************************************************************************************
 * File: MergeSplitTestFilter.java
 * Author: Young-Suk
 *
 * Description:
 *	Sample filter to show splitting to two output ports
 *
 ******************************************************************************************************************/

public class MergeSplitTestFilter extends AbstractArrayMultiPortFilter implements IConfigurable
{
	protected File outFile = null;
	
	protected float splitThreshold = 1.5f;
	protected PipedOutputStream normalOut = null;
	protected PipedOutputStream rejectedOut = null;
	
	public void run()
    {

		int bytesread = 0;					// Number of bytes read from the input file.
		int byteswritten = 0;				// Number of bytes written to the stream.
		byte databyte = 0;					// The byte of data read from the file
		

/*************************************************************
*	This is the main processing loop for the filter. Since this
*   is a sink filter, we read until there is no more data
* 	available on the input port.
**************************************************************/

		// For testing purpose
		DataModel dataModel = null;
		byte[] dataBuffer = new byte[DataModel.BINARY_STREAM_SIZE];
		int recordByteCtr = 0;
		
		SimpleDateFormat timeStampFormat = new SimpleDateFormat("yyyy:MM:dd:hh:mm:ss");
		
		while (true)
		{
			try
			{
				//databyte = ReadFilterInputPort();
				databyte = super.readFilterInputPort(0);

				dataBuffer[recordByteCtr] = databyte;
				recordByteCtr++;
				
				if (dataBuffer.length == recordByteCtr) {
					// this may affect performance
					recordByteCtr = 0;
					dataModel = DataModel.createFromBinary(dataBuffer);
					
					// print to console
					//System.out.printf("\nMergeSplit: %s\t%9.5f\t%11.5f\t%11.5f", timeStampFormat.format(dataModel.getTimestampDt()), dataModel.getTemperature(), dataModel.getAltitude(), dataModel.getPressure());
					
					// [ysahn] This were the split occurs
					if (normalOut != null && dataModel.getTemperature() < this.splitThreshold) {
						try {
							normalOut.write(dataBuffer);
							normalOut.flush();
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					} else if (rejectedOut != null){
						try {
							rejectedOut.write(dataBuffer);
							rejectedOut.flush();
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
					dataBuffer = new byte[DataModel.BINARY_STREAM_SIZE];
				}
			} // try

			
/***************************************************************
*	When we reach the end of the input stream, an exception is
* 	thrown which is shown below. At this point, you should
* 	finish up any processing, close your ports and exit.
***************************************************************/

			catch (EndOfStreamException e)
			{
				ClosePorts();
				
				break;

			} // catch

		} // while

   } // run

	// [ysahn] The configuration actually creates the required output ports.
	@Override
	public void setConfiguration(Properties props)
	{
		if (props != null){
			String id = props.getProperty("normal-portid", null);
			if (id != null)
				normalOut = super.createOutputWritePort(id);
			id = props.getProperty("rejected-portid", null);
			if (id != null)
				rejectedOut = super.createOutputWritePort(id);
			
			this.splitThreshold = Float.parseFloat(props.getProperty("splitThreshold", "1.0"));
		} else {
			normalOut = super.createOutputWritePort("normal");
			rejectedOut = super.createOutputWritePort("rejected");
		}
	}
	

} // FilterTemplate